package com.runda.sec;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import com.bbjob.sec.util.JwtTokenUtils;
import com.runda.exception.TokenException;

import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;

public class JWTAuthorizationFilter extends BasicAuthenticationFilter{
	 Logger logger=LoggerFactory.getLogger(getClass());
	 private UserDetailsService userDetailsService;
	 public JWTAuthorizationFilter(AuthenticationManager authenticationManager,UserDetailsService userDetailsService) {
	        super(authenticationManager);
	        this.userDetailsService=userDetailsService;
	    }

	    @Override
	    protected void doFilterInternal(HttpServletRequest request,
	                                    HttpServletResponse response,
	                                    FilterChain chain) throws IOException, ServletException {

	    	String header = request.getHeader("Authorization");
	        if (header == null || !header.startsWith("Bearer ")) {
	            chain.doFilter(request, response);
	            return;
	        }
	        UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
	        SecurityContextHolder.getContext().setAuthentication(authentication);
	        chain.doFilter(request, response);
	    }
	    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
	        long start = System.currentTimeMillis();
	        String token = request.getHeader("Authorization");
	        if (token == null || token.isEmpty()) {
	            throw new TokenException("Token为空");
	        }
	        // parse the token.
	        String user = null;
	        try {
	            user = JwtTokenUtils.getUsername(token.replace("Bearer ", ""));
	            long end = System.currentTimeMillis();
	            logger.info("执行时间: {}", (end - start) + " 毫秒");
	            if (user != null) {
	            	UserDetails jwtUser= userDetailsService.loadUserByUsername(user);
	                return new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
	            }

	        } catch (ExpiredJwtException e) {
	            logger.error("Token已过期: {} " + e);
	            throw new TokenException("Token已过期");
	        } catch (UnsupportedJwtException e) {
	            logger.error("Token格式错误: {} " + e);
	            throw new TokenException("Token格式错误");
	        } catch (MalformedJwtException e) {
	            logger.error("Token没有被正确构造: {} " + e);
	            throw new TokenException("Token没有被正确构造");
	        } catch (IllegalArgumentException e) {
	            logger.error("非法参数异常: {} " + e);
	            throw new TokenException("非法参数异常");
	        }

	        return null;
	    }
}
